﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Spring.Transaction.Interceptor;

using BOSS.Domain.Security;
using BOSS.Domain.Products;
using BOSS.Dao.Security;
using BOSS.Dao.Products;
using BOSS.Service.Products;
using BOSS.Domain.Customers;
using BOSS.Dao.Customers;
using BOSS.Service.Security;

namespace BOSS.Service.Implements.Products
{
    /// <summary>
    /// 产品管理服务
    /// </summary>
    public class ProductService : EntityService<Product, int, IProductDao>, IProductService
    {
        /// <summary>
        /// 获取 / 设置 账号 DAO
        /// </summary>
        public IAccountDao AccountDao { get; set; }

        /// <summary>
        /// 获取 / 设置 账号服务
        /// </summary>
        public IAccountService AccountService { get; set; }

        /// <summary>
        /// 获取 / 设置 产品购买记录 DAO
        /// </summary>
        public IPurchaseRecordDao PurchaseRecordDao { get; set; }

        /// <summary>
        /// 获取 / 设置 产品消耗记录 DAO
        /// </summary>
        public IConsumptionRecordDao ConsumptionRecordDao { get; set; }

        public ICustomerAccountDao CustomerAccountDao { get; set; }

        /// <summary>
        /// 获取 / 设置 客户账户 DAO
        /// </summary>
        public ICustomerAccountItemDao CustomerAccountItemDao { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="product"></param>
        [Transaction(ReadOnly = false)]
        public override void SaveOrUpdate(Product product)
        {
            this.Prepare(product);

            this.EntityDao.SaveOrUpdate(product);
        }
        
        private void Prepare<T>(T entity) where T : DomainEntity<int>
        {
            DateTime now = DateTime.Now;
            if (entity.Id == 0)
            {
                entity.Creator = this.AccountService.CurrentAccount;
                entity.CreateTime = now;
            }
            entity.Updator = this.AccountService.CurrentAccount;
            entity.UpdateTime = now;
        }

        #region IProductService 成员

        /// <summary>
        /// 购买产品
        /// </summary>
        /// <param name="purchaseRecord"></param>
        /// <returns></returns>
        [Transaction(ReadOnly=false)]
        public int Purchase(PurchaseRecord purchaseRecord)
        {
            this.Prepare(purchaseRecord);
            purchaseRecord.SerialNumber = "PR" + DateTime.Now.ToString("yyMMddHHmmss");
            int returnValue = this.PurchaseRecordDao.Save(purchaseRecord);

            IList<CustomerAccountItem> customerAccountItems = purchaseRecord.CustomerAccount.Items;
            foreach (var item in purchaseRecord.Items)
            {
                CustomerAccountItem exist = customerAccountItems.FirstOrDefault(x => x.Product.Equals(item.Product));
                if (exist != null)
                {
                    exist.ChargedAccumulation += item.ChargedCount;
                    exist.ChargedBalance += item.ChargedCount;
                    exist.DonatedAccumulation += item.DonatedCount;
                    exist.DonatedBalance += item.DonatedCount;
                    this.Prepare(exist);
                }
                else
                {
                    CustomerAccountItem customerAccountItem = new CustomerAccountItem()
                    {
                        CustomerAccount = purchaseRecord.CustomerAccount,
                        Product = item.Product,
                        ChargedAccumulation = item.ChargedCount,
                        ChargedBalance = item.ChargedCount,
                        DonatedAccumulation = item.DonatedCount,
                        DonatedBalance = item.DonatedCount
                    };
                    this.Prepare(customerAccountItem);
                    customerAccountItems.Add(customerAccountItem);
                }
            }

            foreach (var item in customerAccountItems)
            {
                this.CustomerAccountItemDao.SaveOrUpdate(item);
            }

            purchaseRecord.CustomerAccount.LastPurchaseRecord = purchaseRecord;

            this.CustomerAccountDao.SaveOrUpdate(purchaseRecord.CustomerAccount);

            return returnValue;
        }

        /// <summary>
        /// 消耗产品
        /// </summary>
        /// <param name="consumptionRecord"></param>
        /// <returns></returns>
        [Transaction(ReadOnly = false)]
        public int Consume(ConsumptionRecord consumptionRecord)
        {
            this.Prepare(consumptionRecord);
            consumptionRecord.SerialNumber = "CR" + DateTime.Now.ToString("yyMMddHHmmss");
            int returnValue = this.ConsumptionRecordDao.Save(consumptionRecord);

            IList<CustomerAccountItem> customerAccountItems = consumptionRecord.CustomerAccount.Items;
            foreach (var item in consumptionRecord.Items)
            {
                CustomerAccountItem exist = customerAccountItems.FirstOrDefault(x => x.Product.Equals(item.Product));
                if (exist != null)
                {
                    exist.ChargedBalance -= item.ChargedCount;
                    exist.DonatedBalance -= item.DonatedCount;
                    this.Prepare(exist);
                }
            }

            foreach (var item in customerAccountItems)
            {
                this.CustomerAccountItemDao.SaveOrUpdate(item);
            }

            consumptionRecord.CustomerAccount.LastConsumptionRecord = consumptionRecord;
            this.CustomerAccountDao.SaveOrUpdate(consumptionRecord.CustomerAccount);
                                                                          ;
            return returnValue;
        }

        /// <summary>
        /// 获取产品购买记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public PurchaseRecord FindPurchaseRecordById(int id)
        {
            return this.PurchaseRecordDao.FindById(id);
        }

        /// <summary>
        /// 获取产品消耗记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ConsumptionRecord FindConsumptionRecordById(int id)
        {
            return this.ConsumptionRecordDao.FindById(id);
        }

        #endregion
    }
}
